package net.borlis.server.outer;

import net.borlis.processor.dao.entity.MwNodeEntity;
import net.borlis.processor.enumerated.ChangeType;
import net.borlis.server.properties.GeneralProperties;
import net.borlis.server.properties.JdbcProperties;
import net.borlis.server.properties.ServerProperties;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URL;
import java.sql.*;
import java.util.*;
import java.util.Date;

/**
 * Created by borlis on 26.12.2014.
 */
public final class NodeManager {

    private JdbcProperties jdbcConfig;
    private ServerProperties serverConfig;
    private GeneralProperties generalConfig;
    private static final UUID uuid = UUID.randomUUID();
    private static final Date date = Calendar.getInstance().getTime();
    private static String address;


    public NodeManager(
            JdbcProperties config,
            ServerProperties serverProperties,
            GeneralProperties generalConfig) throws Exception {
        this.jdbcConfig = config;
        this.serverConfig = serverProperties;
        this.generalConfig = generalConfig;
        address = getIp() + ":" + serverConfig.getPort();
    }

    private Connection connection() throws ClassNotFoundException, SQLException {
        Class.forName(jdbcConfig.getDriverName());
        return DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUsername(), jdbcConfig.getPassword());
    }

    public List<MwNodeEntity> register() throws Exception {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            String valuesString = "'" + generalConfig.getNodeName()+
                    "', '" + address + "', '" + uuid + "', '" + date + "', '" + date + "', " + "true" + ", '" + date + "', " + generalConfig.getSystemUser() + ", 'I'";
            connection = connection();
            statement = connection.prepareStatement(
                    "INSERT INTO mw_node(" +
                            "node_name, address, uuid, started_on, last_active_on, " +
                            "is_active, changed_on, changed_by, changetype) VALUES (" + valuesString + ");");
            statement.execute();
            statement.close();
            connection.close();
        } catch (SQLException error) {
            error.printStackTrace();
        } finally {
            try {
                if (statement != null)
                    statement.close();
            } catch (SQLException se2) {
                try {
                    if (connection != null)
                        connection.close();
                } catch (SQLException se) {
                    se.printStackTrace();
                }
            }
        }
        return getActiveNodes();
    }


    public List<MwNodeEntity> getActiveNodes() throws Exception {
        List<MwNodeEntity> resultList = new ArrayList<>();
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = connection();
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT * from mw_node WHERE mw_node.is_active = true;";
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                //Retrieve by column name
                MwNodeEntity node = new MwNodeEntity();
                node.setId(new BigInteger(Integer.valueOf(rs.getInt("id")).toString()));
                node.setName(rs.getString("node_name"));
                node.setAddress(rs.getString("address"));
                node.setUuid(UUID.fromString(rs.getString("uuid")));
                node.setStartedOn(rs.getDate("started_on"));
                node.setLastActiveOn(rs.getDate("last_active_on"));
                node.setActive(rs.getBoolean("is_active"));
                node.setChangedBy(rs.getLong("changed_by"));
                node.setChangedOn(rs.getDate("changed_on"));
                node.setChangedType(ChangeType.valueOf(rs.getString("changetype")));
                resultList.add(node);
            }
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
            } catch (SQLException se2) {
                try {
                    if (conn != null)
                        conn.close();
                } catch (SQLException se) {
                    se.printStackTrace();
                }
            }
        }
        return resultList;
    }

    public static String getIp() throws Exception {
        URL whatismyip = new URL("http://checkip.amazonaws.com");
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(
                    whatismyip.openStream()));
            String ip = in.readLine();
            return ip;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
